/**
 *  Copyright 2011 Marco Berri - marcoberri@gmail.com
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and limitations under the License.
 **/
package com.utils;

import java.io.IOException;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.exception.MethodInvocationException;
import org.apache.velocity.exception.ParseErrorException;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.apache.velocity.runtime.RuntimeConstants;

import java.util.*;
import java.io.StringWriter;

/**
 *
 * @author Marco Berri marcoberri@gmail.com
 */
public class VelocityUtil {

    VelocityEngine ve;

    /**
     *
     * @param path 
     */
    public void init(String path) {
        HashMap<String, String> m = new HashMap<String, String>(2);
        m.put("path", path);
        init(m);
    }

    /**
     *
     * @param m
     */
    public void init(HashMap<String, String> m) {

        Properties prop = new Properties();
        if (m.get("log_path") != null) {
            String logPath = IOUtil.normalizedPath(m.get("log_path") + "/template/velocity.log");
            prop.put("runtime.log", logPath);
            prop.put("runtime.log.logsystem.class", "org.apache.velocity.runtime.log.Log4JLogSystem");
            prop.put(RuntimeConstants.OUTPUT_ENCODING, "UTF-8");
            //prop.put("runtime.log.logsystem.class", "biz.minaret.log4j.DatedFileAppender");
            prop.put("runtime.log.error.stacktrace", Default.toString(m.get("error"), "true"));
            prop.put("runtime.log.warn.stacktrace", Default.toString(m.get("warn"), "true"));
            prop.put("runtime.invalid.warn.reference", Default.toString(m.get("warn"), "true"));
            prop.put("runtime.log.info.stacktrace", Default.toString(m.get("info"), "true"));
        }
        prop.put("velocimacro.library.autoreload", "true");
        //parsin degli include max 10 profondità
        prop.put("template.provide.scope.control", "true");
        //prop.put("directive.parse.max.depth", 10);
        prop.put(RuntimeConstants.OUTPUT_ENCODING, "UTF-8");
        //******************   da passare nelle conf
        prop.put(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, m.get("path"));
        prop.put(RuntimeConstants.PARSER_POOL_SIZE, "40");
        this.ve = new VelocityEngine();

        try {
            this.ve.init(prop);
        } catch (Exception ex) {
        }


    }

    /**
     *
     * @param m
     * @param template
     * @return String rendered
     */
    public String render(String template, HashMap<String, Object> m) {

        try {

            Template t = this.ve.getTemplate(template);
            VelocityContext context = new VelocityContext();
            context.put("data", m);
            StringWriter writer = new StringWriter();
            t.merge(context, writer);
            return writer.toString();

        } catch (ResourceNotFoundException ex) {
            return ex.getMessage();
        } catch (ParseErrorException ex) {
            return ex.getMessage();
        } catch (Exception ex) {
            return ex.getMessage();
        }


    }

    /**
     *
     * @param m
     * @param sourceStr
     * @return String rendered
     */
    public String renderString(String sourceStr, HashMap<String, Object> m) {

        try {

            StringWriter w = new StringWriter();
            VelocityContext context = new VelocityContext();
            context.put("data", m);
            return "" + this.ve.evaluate(context, w, "mystring", sourceStr);

        } catch (ParseErrorException ex) {
            return ex.getMessage();
        } catch (MethodInvocationException ex) {
            return ex.getMessage();
        } catch (ResourceNotFoundException ex) {
            return ex.getMessage();
        } catch (IOException ex) {
            return ex.getMessage();
        }
    }
}
